#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
OV7670人脸识别系统 - WSL2 Ubuntu版本
从OV7670相机通过串口接收图像数据并进行实时人脸识别
专为WSL2 Ubuntu 20.04环境优化
"""

import serial
import numpy as np
import cv2
import face_recognition
import time
import os
import glob
import platform
from collections import deque

class OV7670FaceRecognitionWSL2:
    def __init__(self, port='/dev/ttyUSB0', baudrate=921600, debug_mode=False):
        """
        初始化OV7670人脸识别系统 - WSL2版本
        
        Args:
            port: 串口设备路径
            baudrate: 波特率
            debug_mode: 调试模式，True时从test文件夹读取图片进行测试
        """
        self.port = port
        self.baudrate = baudrate
        self.debug_mode = debug_mode
        self.serial_conn = None
        self.running = False
        self.frame_count = 0
        
        # 图像参数
        self.width = 320
        self.height = 240
        self.image_size = self.width * self.height * 2  # RGB565每像素2字节
        
        # 人脸识别相关
        self.known_face_encodings = []
        self.known_face_names = []
        self.face_locations = []
        self.face_encodings = []
        self.face_names = []
        self.process_this_frame = True
        
        # 性能统计
        self.recognition_times = deque(maxlen=10)
        
        # 人脸报警相关
        self.last_alarm_time = 0
        self.alarm_interval = 2.0  # 报警间隔时间（秒），避免过于频繁
        self.alarm_enabled = True  # 是否启用报警功能
        
        # WSL2特定设置
        self.is_wsl = self._check_wsl_environment()
        self.setup_display_environment()
        
        # Debug模式设置
        if self.debug_mode:
            print("🐛 Debug模式已启用 - 将从test文件夹读取图片进行测试")
            self.test_images_dir = "test"
            self.current_test_image_index = 0
        
    def _check_wsl_environment(self):
        """检查是否在WSL环境中"""
        try:
            with open('/proc/version', 'r') as f:
                return 'microsoft' in f.read().lower()
        except:
            return False
    
    def setup_display_environment(self):
        """设置WSL2的显示环境"""
        if self.is_wsl:
            # 设置DISPLAY环境变量（如果使用X11转发）
            if 'DISPLAY' not in os.environ:
                os.environ['DISPLAY'] = ':0.0'
            
            # 检查是否可以显示窗口
            try:
                # 尝试创建一个测试窗口
                test_img = np.zeros((100, 100, 3), dtype=np.uint8)
                cv2.imshow('WSL2_Test', test_img)
                cv2.waitKey(1)
                cv2.destroyWindow('WSL2_Test')
                print("✓ GUI显示环境正常")
            except Exception as e:
                print(f"⚠ GUI显示可能有问题: {e}")
                print("建议:")
                print("1. 安装VcXsrv或X410")
                print("2. 设置DISPLAY环境变量")
                print("3. 或使用无头模式（保存图片而不显示）")
    
    def load_known_faces(self, faces_dir="known_faces"):
        """
        从指定目录加载已知人脸图像
        
        Args:
            faces_dir: 存放已知人脸图像的目录
        """
        if not os.path.exists(faces_dir):
            print(f"创建人脸图像目录: {faces_dir}")
            os.makedirs(faces_dir)
            print(f"请将已知人脸图像放入 {faces_dir} 目录中")
            print("图像文件名将作为人名显示")
            return
        
        supported_formats = ('.jpg', '.jpeg', '.png', '.bmp')
        face_files = [f for f in os.listdir(faces_dir) 
                     if f.lower().endswith(supported_formats)]
        
        if not face_files:
            print(f"在 {faces_dir} 目录中未找到人脸图像文件")
            print("支持的格式: .jpg, .jpeg, .png, .bmp")
            return
        
        print(f"正在加载已知人脸图像...")
        
        for face_file in face_files:
            try:
                # 提取文件名作为人名（去掉扩展名）
                name = os.path.splitext(face_file)[0]
                
                # 加载图像
                image_path = os.path.join(faces_dir, face_file)
                image = face_recognition.load_image_file(image_path)
                
                # 获取人脸编码
                face_encodings = face_recognition.face_encodings(image)
                
                if face_encodings:
                    # 使用第一个检测到的人脸
                    face_encoding = face_encodings[0]
                    self.known_face_encodings.append(face_encoding)
                    self.known_face_names.append(name)
                    print(f"  ✓ 已加载: {name}")
                else:
                    print(f"  ✗ 未检测到人脸: {face_file}")
                    
            except Exception as e:
                print(f"  ✗ 加载失败 {face_file}: {e}")
        
        print(f"共加载 {len(self.known_face_encodings)} 个已知人脸")
    
    def get_test_images(self):
        """获取test文件夹中的测试图像列表"""
        if not os.path.exists(self.test_images_dir):
            print(f"创建测试图像目录: {self.test_images_dir}")
            os.makedirs(self.test_images_dir)
            print(f"请将测试图像放入 {self.test_images_dir} 目录中")
            return []
        
        supported_formats = ('.jpg', '.jpeg', '.png', '.bmp')
        test_files = [f for f in os.listdir(self.test_images_dir) 
                     if f.lower().endswith(supported_formats)]
        
        if not test_files:
            print(f"在 {self.test_images_dir} 目录中未找到测试图像文件")
            print("支持的格式: .jpg, .jpeg, .png, .bmp")
            return []
        
        # 按文件名排序以确保顺序一致
        test_files.sort()
        return test_files
    
    def load_next_test_image(self):
        """加载下一张测试图像"""
        test_files = self.get_test_images()
        
        if not test_files:
            return None
        
        # 循环读取图像
        if self.current_test_image_index >= len(test_files):
            self.current_test_image_index = 0
        
        image_file = test_files[self.current_test_image_index]
        image_path = os.path.join(self.test_images_dir, image_file)
        
        try:
            # 使用OpenCV加载图像
            image = cv2.imread(image_path)
            if image is None:
                print(f"无法读取图像: {image_path}")
                self.current_test_image_index += 1
                return None
            
            # 转换为RGB格式（face_recognition库使用RGB）
            rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            
            original_height, original_width = rgb_image.shape[:2]
            
            if self.debug_mode:
                # Debug模式：保持原始图像尺寸，不进行resize
                print(f"🖼️  加载测试图像: {image_file} ({self.current_test_image_index + 1}/{len(test_files)}) - 尺寸: {original_width}x{original_height} (保持原始尺寸)")
            else:
                # 非Debug模式：调整到相机分辨率
                rgb_image = cv2.resize(rgb_image, (self.width, self.height))
                print(f"🖼️  加载测试图像: {image_file} ({self.current_test_image_index + 1}/{len(test_files)}) - 原始: {original_width}x{original_height} → 调整为: {self.width}x{self.height}")
            
            self.current_test_image_index += 1
            return rgb_image
            
        except Exception as e:
            print(f"加载测试图像失败 {image_file}: {e}")
            self.current_test_image_index += 1
            return None
    
    def connect_serial(self):
        """连接串口，优化Linux环境"""
        try:
            self.serial_conn = serial.Serial(
                port=self.port,
                baudrate=self.baudrate,
                bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE,
                timeout=5,
                xonxoff=False,
                rtscts=False,
                dsrdtr=False
            )
            
            # Linux下设置缓冲区
            try:
                self.serial_conn.set_buffer_size(rx_size=256000, tx_size=4096)
            except AttributeError:
                # 某些系统可能不支持这个方法
                pass
            
            print(f"已连接到串口 {self.port}，波特率 {self.baudrate}")
            return True
        except serial.SerialException as e:
            print(f"串口连接失败: {e}")
            if "Permission denied" in str(e):
                print("权限错误解决方案:")
                print("1. 添加用户到dialout组: sudo usermod -a -G dialout $USER")
                print("2. 重新登录或重启WSL2")
                print("3. 或临时使用: sudo chmod 666 /dev/ttyUSB*")
            return False
        except Exception as e:
            print(f"串口连接失败: {e}")
            return False
    
    def disconnect_serial(self):
        """断开串口连接"""
        if self.serial_conn and self.serial_conn.is_open:
            self.serial_conn.close()
            print("串口已断开")
    
    def rgb565_to_rgb888(self, data):
        """RGB565格式转换为RGB888"""
        try:
            if len(data) != self.image_size:
                return None
                
            # 转换为16位整数数组（小端序）
            rgb565_data = np.frombuffer(data, dtype=np.uint16)
            
            # 位运算提取RGB分量
            r = ((rgb565_data & 0xF800) >> 8).astype(np.uint8)
            g = ((rgb565_data & 0x07E0) >> 3).astype(np.uint8)
            b = ((rgb565_data & 0x001F) << 3).astype(np.uint8)
            
            # 组合RGB数组
            rgb888 = np.stack([r, g, b], axis=-1)
            return rgb888.reshape(self.height, self.width, 3)
            
        except Exception as e:
            print(f"图像格式转换错误: {e}")
            return None
    
    def receive_frame(self):
        """接收一帧图像数据"""
        if not self.serial_conn or not self.serial_conn.is_open:
            return None
        
        try:
            # 等待帧开始标识
            timeout_counter = 0
            while timeout_counter < 50:
                line = self.serial_conn.readline().decode('utf-8', errors='ignore').strip()
                if line.startswith('FRAME_START:'):
                    frame_num = int(line.split(':')[1])
                    break
                timeout_counter += 1
                time.sleep(0.1)
            else:
                return None
            
            # 跳过元数据，找到DATA_START
            while True:
                line = self.serial_conn.readline().decode('utf-8', errors='ignore').strip()
                if line == 'DATA_START':
                    break
                if not line:
                    continue
            
            # 接收图像数据
            image_data = b''
            bytes_received = 0
            chunk_size = 4096
            
            while bytes_received < self.image_size:
                remaining = self.image_size - bytes_received
                read_size = min(chunk_size, remaining)
                
                chunk = self.serial_conn.read(read_size)
                if not chunk:
                    return None
                
                image_data += chunk
                bytes_received += len(chunk)
            
            # 转换图像格式
            rgb888_image = self.rgb565_to_rgb888(image_data)
            if rgb888_image is None:
                return None
            
            return rgb888_image
            
        except Exception as e:
            print(f"接收图像失败: {e}")
            return None
    
    def recognize_faces(self, frame):
        """
        在图像中识别人脸
        
        Args:
            frame: RGB图像数组
            
        Returns:
            处理后的BGR图像（用于OpenCV显示）
        """
        recognition_start = time.time()
        
        # 只在每隔一帧处理人脸识别以提高性能
        if self.process_this_frame:
            # 不缩小图像，保持原始尺寸以获得更好的显示效果
            rgb_frame = frame
            
            # 检测人脸位置和编码
            self.face_locations = face_recognition.face_locations(rgb_frame, model="hog")  # 使用HOG模型更快
            self.face_encodings = face_recognition.face_encodings(rgb_frame, self.face_locations)
            
            self.face_names = []
            for face_encoding in self.face_encodings:
                # 与已知人脸进行比较
                matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding, tolerance=0.6)
                name = "Unknown"
                
                # 如果有已知人脸数据，找到最匹配的
                if self.known_face_encodings:
                    face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding)
                    best_match_index = np.argmin(face_distances)
                    if matches[best_match_index]:
                        name = self.known_face_names[best_match_index]
                
                self.face_names.append(name)
        
        self.process_this_frame = not self.process_this_frame
        
        # 转换为BGR格式用于OpenCV显示
        bgr_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        
        # 在图像上绘制人脸框和名称（使用原始坐标，无需缩放）
        for (top, right, bottom, left), name in zip(self.face_locations, self.face_names):
            # 绘制人脸框（增加线条粗细）
            cv2.rectangle(bgr_frame, (left, top), (right, bottom), (0, 0, 255), 4)
            
            # 计算标签尺寸（增大字体）
            font = cv2.FONT_HERSHEY_DUPLEX
            font_scale = 1.2  # 从0.8增加到1.2
            thickness = 3     # 从2增加到3
            (text_width, text_height), baseline = cv2.getTextSize(name, font, font_scale, thickness)
            
            # 标签背景位置（在人脸框上方）
            label_top = top - text_height - 15  # 增加间距
            label_bottom = top - 5
            
            # 确保标签不会超出图像顶部
            if label_top < 0:
                label_top = bottom + 10
                label_bottom = bottom + text_height + 20
            
            # 绘制姓名标签背景（增加背景大小）
            cv2.rectangle(bgr_frame, (left, label_top), (left + text_width + 20, label_bottom), (0, 0, 255), cv2.FILLED)
            
            # 绘制姓名文字
            cv2.putText(bgr_frame, name, (left + 10, label_bottom - 10), font, font_scale, (255, 255, 255), thickness)
        
        # 记录识别时间
        recognition_time = time.time() - recognition_start
        self.recognition_times.append(recognition_time)
        
        # 显示性能信息（增大字体）
        if len(self.recognition_times) > 0:
            avg_time = sum(self.recognition_times) / len(self.recognition_times)
            fps = 1.0 / avg_time if avg_time > 0 else 0
            
            # 在图像上显示FPS和检测到的人脸数（增大字体和粗细）
            cv2.putText(bgr_frame, f"FPS: {fps:.1f}", (20, 50), 
                       cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 3)
            cv2.putText(bgr_frame, f"Faces: {len(self.face_locations)}", (20, 100), 
                       cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 3)
            
            # 显示WSL2标识（增大字体）
            if self.is_wsl:
                cv2.putText(bgr_frame, "WSL2", (20, 150), 
                           cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 0), 2)
            
            # 显示报警状态
            alarm_status = "ON" if self.alarm_enabled else "OFF"
            alarm_color = (0, 255, 0) if self.alarm_enabled else (0, 0, 255)
            cv2.putText(bgr_frame, f"Alarm: {alarm_status}", (20, 200), 
                       cv2.FONT_HERSHEY_SIMPLEX, 1.0, alarm_color, 2)
        
        # 人脸检测报警逻辑
        if len(self.face_locations) > 0 and not self.debug_mode:
            # 统计已知和未知人脸
            known_count = sum(1 for name in self.face_names if name != "Unknown")
            unknown_count = sum(1 for name in self.face_names if name == "Unknown")
            total_faces = len(self.face_locations)
            
            # 发送报警数据到STM32
            self.send_face_alarm(total_faces, known_count, unknown_count)
        
        return bgr_frame
    
    def start_recognition(self):
        """开始人脸识别"""
        if self.debug_mode:
            print("正在启动OV7670人脸识别系统 (Debug模式)...")
        else:
            print("正在启动OV7670人脸识别系统 (WSL2版本)...")
        
        # 加载已知人脸
        self.load_known_faces()
        
        # Debug模式不需要连接串口
        if not self.debug_mode:
            if not self.connect_serial():
                return
        else:
            # 检查test文件夹
            test_files = self.get_test_images()
            if not test_files:
                print("Debug模式需要在test文件夹中放入测试图像")
                return
            print(f"Debug模式找到 {len(test_files)} 张测试图像")
        
        self.running = True
        
        if self.debug_mode:
            print("Debug模式控制键:")
            print("  'q' - 退出程序")
            print("  's' - 保存当前帧")
            print("  'r' - 重新加载已知人脸")
            print("  'n' - 下一张测试图像")
            print("  'space' - 暂停/继续自动切换")
            print("  'a' - 切换报警功能开关")
        else:
            print("开始人脸识别，按 'q' 键退出，按 's' 键保存当前帧...")
            print("控制键:")
            print("  'q' - 退出程序")
            print("  's' - 保存当前帧")
            print("  'r' - 重新加载已知人脸")
            print("  'a' - 切换报警功能开关")
        
        # 清空串口缓冲区（仅非Debug模式）
        if not self.debug_mode and self.serial_conn:
            self.serial_conn.flushInput()
        
        last_frame_time = time.time()
        auto_switch = True  # Debug模式下是否自动切换图像
        last_auto_switch_time = time.time()
        auto_switch_interval = 3.0  # 自动切换间隔（秒）
        
        # 检查是否可以显示GUI
        can_display_gui = True
        try:
            window_title = 'OV7670 Face Recognition - Debug Mode' if self.debug_mode else 'OV7670 Face Recognition - WSL2'
            cv2.namedWindow(window_title, cv2.WINDOW_NORMAL)
            # 设置窗口初始大小（让窗口更大）
            cv2.resizeWindow(window_title, 1200, 900)
        except Exception as e:
            print(f"GUI显示不可用: {e}")
            print("将以无头模式运行，图像将保存到文件")
            can_display_gui = False
        
        while self.running:
            frame = None
            
            if self.debug_mode:
                # Debug模式：从test文件夹读取图像
                current_time = time.time()
                should_load_new_image = False
                
                if self.frame_count == 0:
                    # 第一次运行，加载第一张图像
                    should_load_new_image = True
                    last_auto_switch_time = current_time
                elif auto_switch and (current_time - last_auto_switch_time) >= auto_switch_interval:
                    # 自动切换模式且时间间隔到了
                    test_files = self.get_test_images()
                    if len(test_files) > 1:  # 只有多张图片时才自动切换
                        should_load_new_image = True
                        last_auto_switch_time = current_time
                    else:
                        # 只有一张图片时，重置时间但不重新加载
                        last_auto_switch_time = current_time
                
                if should_load_new_image:
                    frame = self.load_next_test_image()
                    if frame is not None:
                        self.last_debug_frame = frame.copy()
                
                # 如果没有新图像，使用上一张图像（避免空白）
                if frame is None and hasattr(self, 'last_debug_frame'):
                    frame = self.last_debug_frame
                    
            else:
                # 正常模式：接收串口图像帧
                frame = self.receive_frame()

            if frame is not None:
                self.frame_count += 1
                
                # 进行人脸识别
                processed_frame = self.recognize_faces(frame)
                
                # 显示或保存结果
                if can_display_gui:
                    try:
                        window_title = 'OV7670 Face Recognition - Debug Mode' if self.debug_mode else 'OV7670 Face Recognition - WSL2'
                        cv2.imshow(window_title, processed_frame)
                        
                        # 检查按键
                        key = cv2.waitKey(1 if not self.debug_mode else 100) & 0xFF
                        if key == ord('q'):
                            break
                        elif key == ord('s'):
                            # 保存当前帧
                            mode_prefix = "debug" if self.debug_mode else "serial"
                            filename = f'{mode_prefix}_face_recognition_frame_{self.frame_count}_{int(time.time())}.jpg'
                            cv2.imwrite(filename, processed_frame)
                            print(f"\n已保存图像: {filename}")
                        elif key == ord('r'):
                            # 重新加载已知人脸
                            print("\n重新加载已知人脸...")
                            self.known_face_encodings = []
                            self.known_face_names = []
                            self.load_known_faces()
                        elif self.debug_mode and key == ord('n'):
                            # Debug模式：手动切换到下一张图像
                            test_files = self.get_test_images()
                            if len(test_files) > 1:
                                frame = self.load_next_test_image()
                                if frame is not None:
                                    self.last_debug_frame = frame.copy()
                            else:
                                print("\n只有一张测试图像，无需切换")
                        elif self.debug_mode and key == ord(' '):  # 空格键
                            # Debug模式：切换自动/手动模式
                            auto_switch = not auto_switch
                            status = "自动" if auto_switch else "手动"
                            print(f"\n切换到{status}模式")
                            if auto_switch:
                                last_auto_switch_time = time.time()
                        elif key == ord('a'):
                            # 切换报警功能开关
                            self.toggle_alarm()
                            
                    except Exception as e:
                        print(f"GUI显示错误: {e}")
                        can_display_gui = False
                else:
                    # 无头模式，定期保存图像
                    if self.frame_count % 10 == 0:
                        mode_prefix = "debug" if self.debug_mode else "headless"
                        filename = f'{mode_prefix}_frame_{self.frame_count}.jpg'
                        cv2.imwrite(filename, processed_frame)
                        print(f"保存图像: {filename}")
                
                # 显示帧率信息
                current_time = time.time()
                frame_interval = current_time - last_frame_time
                if frame_interval > 0:
                    frame_fps = 1.0 / frame_interval
                    mode_info = " (Debug)" if self.debug_mode else ""
                    print(f"\r帧 {self.frame_count}{mode_info}: {frame_fps:.1f} FPS", end='', flush=True)
                last_frame_time = current_time
                
                # Debug模式或无头模式下的退出条件
                if not can_display_gui and self.frame_count >= (20 if self.debug_mode else 100):
                    exit_frames = 20 if self.debug_mode else 100
                    print(f"\n无头模式运行{exit_frames}帧后自动退出")
                    break
                
            else:
                if not self.debug_mode:
                    time.sleep(0.05)
                else:
                    # Debug模式下如果没有图像，稍作等待
                    time.sleep(0.1)
        
        # 清理资源
        if can_display_gui:
            cv2.destroyAllWindows()
        if not self.debug_mode:
            self.disconnect_serial()
        
        mode_info = " (Debug模式)" if self.debug_mode else ""
        print(f"\n人脸识别系统结束{mode_info}，共处理 {self.frame_count} 帧图像")

    def send_face_alarm(self, face_count, known_faces, unknown_faces):
        """
        发送人脸检测报警标志位到STM32下位机
        
        Args:
            face_count: 检测到的人脸总数
            known_faces: 已知人脸数量
            unknown_faces: 未知人脸数量
        """
        if not self.alarm_enabled or not self.serial_conn or not self.serial_conn.is_open:
            return
        
        current_time = time.time()
        
        # 检查报警间隔，避免过于频繁
        if current_time - self.last_alarm_time < self.alarm_interval:
            return
        
        try:
            # 发送简单的报警标志位：1表示检测到人脸
            alarm_signal = "1\n"
            
            # 发送数据到串口
            self.serial_conn.write(alarm_signal.encode('utf-8'))
            self.serial_conn.flush()
            
            # 更新最后报警时间
            self.last_alarm_time = current_time
            
            # 打印报警信息
            print(f"\n🚨 报警信号已发送: 检测到 {face_count} 张人脸")
            
        except Exception as e:
            print(f"\n报警发送失败: {e}")
    
    def toggle_alarm(self):
        """切换报警功能开关"""
        self.alarm_enabled = not self.alarm_enabled
        status = "启用" if self.alarm_enabled else "禁用"
        print(f"\n报警功能已{status}")
        return self.alarm_enabled

def list_serial_ports():
    """列出可用的串口设备"""
    # Linux下的串口设备
    port_patterns = ['/dev/ttyUSB*', '/dev/ttyACM*', '/dev/ttyS*']
    available_ports = []
    
    for pattern in port_patterns:
        ports = glob.glob(pattern)
        available_ports.extend(ports)
    
    # 过滤出真正可用的端口
    working_ports = []
    for port in available_ports:
        try:
            with serial.Serial(port, timeout=0.1) as ser:
                working_ports.append(port)
        except:
            continue
    
    print("可用的串口设备:")
    for i, port in enumerate(working_ports):
        try:
            # 获取设备信息
            info = f"{port}"
            if os.path.exists(port):
                stat = os.stat(port)
                info += f" (权限: {oct(stat.st_mode)[-3:]})"
            print(f"{i+1}. {info}")
        except:
            print(f"{i+1}. {port}")
    
    return working_ports

def main():
    """主函数"""
    print("OV7670人脸识别系统 - WSL2 Ubuntu版本")
    print("===================================")
    
    # 检查WSL环境
    try:
        with open('/proc/version', 'r') as f:
            if 'microsoft' in f.read().lower():
                print("✓ 检测到WSL2环境")
            else:
                print("⚠ 未检测到WSL2环境，可能在原生Linux中运行")
    except:
        pass
    
    print("功能说明:")
    print("- 从OV7670相机通过串口接收图像")
    print("- 实时进行人脸检测和识别")
    print("- 支持多人脸同时识别")
    print("- 适配WSL2环境")
    print("- 支持Debug模式测试")
    print()
    
    # 检查face_recognition库
    try:
        import face_recognition
        print("✓ face_recognition库已安装")
    except ImportError:
        print("✗ 未安装face_recognition库")
        print("请运行启动脚本进行安装")
        return
    
    # 选择运行模式
    print("运行模式:")
    print("1. 正常模式 - 从串口接收OV7670相机数据")
    print("2. Debug模式 - 从test文件夹读取图片进行测试")
    
    try:
        mode_choice = input("请选择模式 (1/2，默认1): ").strip()
        debug_mode = (mode_choice == '2')
    except (ValueError, KeyboardInterrupt):
        print("使用默认正常模式")
        debug_mode = False
    
    if debug_mode:
        print("\n🐛 Debug模式选择")
        print("系统将从test文件夹读取图片进行人脸识别测试")
        print("请确保test文件夹中有测试图片文件")
        
        # 创建人脸识别系统（Debug模式）
        face_recognition_system = OV7670FaceRecognitionWSL2(debug_mode=True)
        
        print("\nDebug模式控制说明:")
        print("  'q' - 退出程序")
        print("  's' - 保存当前帧")
        print("  'r' - 重新加载已知人脸")
        print("  'n' - 手动切换到下一张图像")
        print("  'space' - 切换自动/手动模式")
        print("  'a' - 切换报警功能开关")
        print()
        
        try:
            face_recognition_system.start_recognition()
        except KeyboardInterrupt:
            print("\n用户中断程序")
            face_recognition_system.running = False
        
        return
    
    # 正常模式的串口设置
    # 列出可用串口
    available_ports = list_serial_ports()
    
    if not available_ports:
        print("未找到可用的串口设备")
        print("WSL2用户请参考:")
        print("1. 使用 usbipd-win 转发USB设备")
        print("2. 或在Windows运行串口转发服务")
        print("3. 或使用Debug模式进行测试")
        return
    
    # 选择串口
    if len(available_ports) == 1:
        selected_port = available_ports[0]
        print(f"自动选择唯一可用串口: {selected_port}")
    else:
        try:
            port_index = int(input("请选择串口 (输入数字): ")) - 1
            if 0 <= port_index < len(available_ports):
                selected_port = available_ports[port_index]
            else:
                print("无效的选择，使用第一个可用串口")
                selected_port = available_ports[0]
        except ValueError:
            print("无效输入，使用第一个可用串口")
            selected_port = available_ports[0]
    
    # 选择波特率
    baudrates = [115200, 460800, 921600]
    print("\n可用波特率:")
    for i, br in enumerate(baudrates):
        print(f"{i+1}. {br}")
    
    try:
        br_index = int(input("请选择波特率 (输入数字，默认3): ")) - 1
        if 0 <= br_index < len(baudrates):
            selected_baudrate = baudrates[br_index]
        else:
            selected_baudrate = 921600
    except ValueError:
        selected_baudrate = 921600
    
    print(f"\n使用配置: {selected_port} @ {selected_baudrate}")
    print("控制键:")
    print("  'q' - 退出程序")
    print("  's' - 保存当前帧")
    print("  'r' - 重新加载已知人脸")
    print("  'a' - 切换报警功能开关")
    
    # 创建人脸识别系统（正常模式）
    face_recognition_system = OV7670FaceRecognitionWSL2(
        port=selected_port, 
        baudrate=selected_baudrate,
        debug_mode=False
    )
    
    try:
        face_recognition_system.start_recognition()
    except KeyboardInterrupt:
        print("\n用户中断程序")
        face_recognition_system.running = False

if __name__ == "__main__":
    main() 